/*
Copyright 2012 Eiji Kitamura

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Author: Eiji Kitamura (agektmr@gmail.com)
*/
'use_strict';

var flexDemo = angular.module('flexDemo', []);

flexDemo.value('model', {
  flexDirection: "row",
  flexWrap: "nowrap",
  justifyContent: "center",
  alignContent: "center",
  alignItems: "center"
});

flexDemo.value('text', {
  flexText: "flex 规定了弹性元素如何伸长或缩短以适应flex容器中的可用空间。这是一个简写属性，用来设置 flex-grow, flex-shrink 与 flex-basis。",
  flexGrowText: "flex-grow设置了一个flex项主尺寸的flex增长系数。它指定了flex容器中剩余空间的多少应该分配给项目（flex增长系数）。",
  flexShrinkText: "flex-shrink 属性指定了 flex 元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩，其收缩的大小是依据 flex-shrink 的值。",
  flexBasisText: "flex-basis 指定了 flex 元素在主轴方向上的初始大小。",
  flexFlowText: "flex-flow 属性是 flex-direction 和 flex-wrap 的简写。",
  flexDirectionText: "flex-direction 属性指定了内部元素是如何在 flex 容器中布局的，定义了主轴的方向(正方向或反方向)。",
  flexWrapText: "flex-wrap 指定 flex 元素单行显示还是多行显示 。如果允许换行，这个属性允许你控制行的堆叠方向。",
  justifyContentText: "justify-content 属性定义了浏览器之间，如何分配顺着弹性容器主轴(或者网格行轴) 的元素之间及其周围的空间。",
  alignContentText: "align-content 属性设置了浏览器如何沿着弹性盒子布局的纵轴和网格布局的主轴在内容项之间和周围分配空间。",
  alignItemsText: "align-items属性将所有直接子节点上的align-self值设置为一个组。 align-self属性设置项目在其包含块中在交叉轴方向上的对齐方式。",
  alignSelfText: "align-self 会对齐当前 grid 或 flex 行中的元素，并覆盖已有的 align-items 的值。在 Flexbox 中，会按照 cross axis（当前 flex 元素排列方向的垂直方向）进行排列。",
  orderText: "order 属性规定了弹性容器中的可伸缩项目在布局时的顺序。元素按照 order 属性的值的增序进行布局。拥有相同 order 属性值的元素按照它们在源代码中出现的顺序进行布局。"
});

flexDemo.value('boxes', {});
flexDemo.value('box_list', ['A', 'B', 'C']);

flexDemo.controller('FlexboxCtrl', function($scope, model, text, boxes, box_list) {
  $scope.model = model;
  $scope.text = text;
  $scope.boxes = boxes;
  $scope.box_list = box_list;

  $scope.flexOpen = false;
  $scope.flexFlowOpen = false;
  var names = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'];
  $scope.add_box = function() {
    if ($scope.box_list.length < 10) {
      $scope.box_list.push(names[$scope.box_list.length]);
    }
  };
  $scope.remove_box = function() {
    if ($scope.box_list.length > 2) {
      var box = $scope.box_list.pop();
      delete $scope.boxes[box];
    }
  };
});

flexDemo.directive('boxVisual', function(box_list) {
  return {
    link: function($scope, $element, attrs) {
      $scope.box_list = box_list;
      var draw = function(list) {
        var html = '<pre>&lt;div class="box"&gt;\n';
        for (var i = 0; i < list.length; i++) {
          html += '  &lt;div class="'+list[i]+'"&gt;'+list[i]+'&lt;/div&gt;\n';
        }
        html += '&lt;/div&gt;</pre>';
        $element.html(html);
      };
      draw($scope.box_list);
      // How do I reflect that box is being added?
      $scope.$watch('box_list', function(newValue, oldValue) {
        draw(newValue);
      }, true);
    }
  };
});

flexDemo.directive('boxDefinition', function(boxes, text) {
  return {
    templateUrl: 'box-definition.html',
    scope: {
      name: '=boxDefinition',
      index: '='
    },
    link: function($scope, $element, attrs) {
      $scope.text = text;
      $scope.box = boxes[$scope.name] = {
        order: $scope.index + 1,
        flexGrow: 0,
        flexShrink: 1,
        flexBasis: "auto",
        alignSelf: "auto",
        minWidth: 0,
        minHeight: "auto",
        hoverItem: false,
        flexOpen: false
      };
    }
  };
});

flexDemo.filter('vendorPrefix', function() {
  var prefixes = ['webkit', 'moz', 'ms', 'o'];
  return function(styles) {
    var new_styles = {};
    for (var key in styles) {
      if (key.indexOf('$') === 0) continue;
      new_styles[key] = styles[key];
      var upper = key.charAt(0).toUpperCase() + key.slice(1);
      prefixes.forEach(function(prefix) {
        new_styles[prefix + upper] = styles[key];
      });
    }
    return new_styles;
  };
});